package com.googlecode.jlogindexer.utils;

import static com.googlecode.jlogindexer.log4j.JLogIndexerConstants.CLASS_STRING;
import static com.googlecode.jlogindexer.log4j.JLogIndexerConstants.FILE_STRING;
import static com.googlecode.jlogindexer.log4j.JLogIndexerConstants.LEVEL_STRING;
import static com.googlecode.jlogindexer.log4j.JLogIndexerConstants.LINE_STRING;
import static com.googlecode.jlogindexer.log4j.JLogIndexerConstants.MESSAGE_STRIMG;
import static com.googlecode.jlogindexer.log4j.JLogIndexerConstants.METHOD_STRING;
import static com.googlecode.jlogindexer.log4j.JLogIndexerConstants.THREAD_STRING;
import static com.googlecode.jlogindexer.log4j.JLogIndexerConstants.THROWABLE_STRING;
import static com.googlecode.jlogindexer.log4j.JLogIndexerConstants.TIMESTAMP_STRING;
import static com.googlecode.jlogindexer.log4j.JLogIndexerConstants.EVENT_STRING;
import static com.googlecode.jlogindexer.log4j.JLogIndexerConstants.LOGGER_STRING;

import java.io.IOException;
import java.util.Date;

import org.apache.commons.lang.StringEscapeUtils;
import org.codehaus.jackson.JsonFactory;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonToken;

import com.googlecode.jlogindexer.document.LogDocument;

public class JsonUtils {
	
	public static JsonFactory factory=null;
	
	static{
		factory=new JsonFactory();
	}

	public static LogDocument mapJsonStringToLogDocument(String jsonString)  {

		LogDocument logDocument=null;
		try {
			System.err.println("Log document is being created.......");
			JsonParser jsonParser = factory.createJsonParser(jsonString);
			
			logDocument = new LogDocument();
			
			jsonParser.nextToken(); //move to START_OBJECT
			
			String fieldname=null;
			long timeInMillis=0;
			
			while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
			  fieldname = jsonParser.getCurrentName();
			  jsonParser.nextToken(); // move to value, or START_OBJECT/START_ARRAY
			  
			  if (TIMESTAMP_STRING.equals(fieldname)) {
				timeInMillis=jsonParser.getLongValue();
			    logDocument.setTimestamp(new Date(timeInMillis));
			  } else if (LEVEL_STRING.equals(fieldname)) {
			    logDocument.setLevel(jsonParser.getText());
			  }else if (THREAD_STRING.equals(fieldname)) {
			    logDocument.setThreadName(jsonParser.getText());
			  }else if (CLASS_STRING.equals(fieldname)) {
			    logDocument.setClassName(jsonParser.getText());
			  }else if (FILE_STRING.equals(fieldname)) {
			    logDocument.setFileName(jsonParser.getText());
			  }else if (METHOD_STRING.equals(fieldname)) {
			    logDocument.setMethodName(jsonParser.getText());
			  }else if (LINE_STRING.equals(fieldname)) {
			    logDocument.setLineNumber(jsonParser.getIntValue());
			  }else if (MESSAGE_STRIMG.equals(fieldname)) {
				String jsonParserText=jsonParser.getText();
				System.out.println("Json parser text::::"+jsonParserText);
			    logDocument.setOutMessage(StringEscapeUtils.escapeJavaScript(jsonParserText));
			  } else if (THROWABLE_STRING.equals(fieldname)) {
			    logDocument.setErrorMessage(jsonParser.getText());
			  }	else if (EVENT_STRING.equals(fieldname) || LOGGER_STRING.equals(fieldname)) {
				    jsonParser.getText();//Just skip on to the next object
				  }else {
			    throw new IllegalStateException("Unrecognized field '"+fieldname+"'!");
			  }
			  
			  fieldname=null;
			  
			}
			
			logDocument.setId(timeInMillis);
		} catch (JsonParseException e) {
			System.err.println("Could not parse Json. God knows why"+e.getMessage());
			//Printing Json String ... for debugging
			System.err.println("The slipped in rogue Json is....."+jsonString);
		} catch (IOException e) {
			System.err.println("IO Exception for no reason at all... "+e.getMessage());
		}
		finally{
			jsonString=null;
		}
		
		System.out.println("Log document is......"+logDocument);
		return logDocument;
	}

}
